
#include "ST7735.h"


#define DELAY 0x80


void ST7735_spiWrite(uint8_t dt)
{
    // must use HAL_SPI_TransmitReceive - wait for whole byte transmission
    uint8_t rx;
    while(HAL_SPI_TransmitReceive(&hspi1, &dt, &rx, 1, HAL_MAX_DELAY) == HAL_BUSY);
}


void ST7735_WriteCommand(uint8_t cmd)
{
    ST7735_SELECT_COMMAND
    HAL_SPI_Transmit(&hspi1, &cmd, sizeof(cmd), HAL_MAX_DELAY);
}

void st7735_sendData(uint8_t dt)
{
    ST7735_SELECT_DATA
    ST7735_spiWrite(dt);
}

static void ST7735_WriteData(uint8_t* buff, uint16_t size)
{

    ST7735_SELECT_DATA
    HAL_SPI_Transmit(&hspi1, buff, size, HAL_MAX_DELAY);
}
static void ST7735_ExecuteCommandList(const uint8_t *addr)
{
    uint8_t numCommands, numArgs;
    uint16_t ms;

    numCommands = *addr++;
    while(numCommands--)
    {
        uint8_t cmd = *addr++;
        ST7735_WriteCommand(cmd);

        numArgs = *addr++;
        // If high bit set, delay follows args
        ms = numArgs & DELAY;
        numArgs &= ~DELAY;
        if(numArgs)
        {
            ST7735_WriteData((uint8_t*)addr, numArgs);
            addr += numArgs;
        }

        if(ms)
        {
            ms = *addr++;
            if(ms == 255) ms = 500;
            HAL_Delay(ms);
        }
    }
}

static void ST7735_SetAddressWindow(uint8_t x0, uint8_t y0, uint8_t x1, uint8_t y1)
{
    // column address set
    ST7735_WriteCommand(ST7735_CASET);
    uint8_t data[] = { 0x00, x0 + ST7735_XSTART, 0x00, x1 + ST7735_XSTART };
    ST7735_WriteData(data, sizeof(data));

    // row address set
    ST7735_WriteCommand(ST7735_RASET);
    data[1] = y0 + ST7735_YSTART;
    data[3] = y1 + ST7735_YSTART;
    ST7735_WriteData(data, sizeof(data));

    // write to RAM
    ST7735_WriteCommand(ST7735_RAMWR);
}









// for ST7735R
void ST7735_InitR(void)
{
}
// for ST7735B
void ST7735_InitB(void)
{
//      ST7735_Select();
//      ST7735_Reset();
//      ST7735_ExecuteCommandList(init_cmds1);
//      ST7735_ExecuteCommandList(init_cmds2);
//      ST7735_ExecuteCommandList(init_cmds3);
//      ST7735_Unselect();
}


void ST7735_DrawPixel(uint16_t x, uint16_t y, uint16_t color)
{
    if((x >= ST7735_WIDTH) || (y >= ST7735_HEIGHT))
        return;

    ST7735_CS_ENABLE

    ST7735_SetAddressWindow(x, y, x + 1, y + 1);
    uint8_t data[] = { color >> 8, color & 0xFF };
    ST7735_WriteData(data, sizeof(data));

    ST7735_CS_DISABLE
}



void ST7735_FillRectangle(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color)
{
    // clipping
    if((x >= ST7735_WIDTH) || (y >= ST7735_HEIGHT)) return;
    if((x + w - 1) >= ST7735_WIDTH) w = ST7735_WIDTH - x;
    if((y + h - 1) >= ST7735_HEIGHT) h = ST7735_HEIGHT - y;

    ST7735_CS_ENABLE
    ST7735_SetAddressWindow(x, y, x + w - 1, y + h - 1);

    uint8_t data[] = { color >> 8, color & 0xFF };
//      HAL_GPIO_WritePin(ST7735_DC_GPIO_Port, ST7735_DC_Pin, GPIO_PIN_SET);
    ST7735_SELECT_DATA
    for(y = h; y > 0; y--)
    {
        for(x = w; x > 0; x--)
        {
            HAL_SPI_Transmit(&hspi1, data, sizeof(data), HAL_MAX_DELAY);
        }
    }

    ST7735_CS_DISABLE
}

void ST7735_FillScreen(uint16_t color)
{
    ST7735_FillRectangle(0, 0, ST7735_WIDTH, ST7735_HEIGHT, color);
}







